home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 101-125 / 118 / empire / src / source.zoo / serial.d < prev    next >
Text File  |  1987-12-02  |  8KB  |  366 lines

  1. #include:exec/io.g
  2. #include:exec/ports.g
  3. #include:devices/serial.g
  4. #include:hardware/cia.g
  5. #include:libraries/dos.g
  6.  
  7. uint LINE_BUFFER_LENGTH = 100;
  8.  
  9. [LINE_BUFFER_LENGTH] char LineBuffer;
  10. uint
  11.     LineBuffPos,
  12.     LineBuffMax,
  13.     LineSpeed;
  14. bool EchoOn, SerialDropped;
  15.  
  16. *MsgPort_t MySerPort;
  17. *IOExtSer_t MySerReq;
  18. IOExtSer_t SaveParams;
  19.  
  20. /*
  21.  * setDTRoff - force DTR off.
  22.  */
  23.  
  24. proc setDTRoff()void:
  25.  
  26.     CIAB.cia_ciapra := CIAB.cia_ciapra | CIAF_COMDTR;
  27. corp;
  28.  
  29. /*
  30.  * setDTRon - force DTR on.
  31.  */
  32.  
  33. proc setDTRon()void:
  34.  
  35.     CIAB.cia_ciapra := CIAB.cia_ciapra & ~CIAF_COMDTR;
  36. corp;
  37.  
  38. /*
  39.  * checkDoIO - do and check a DoIO call for the serial device.
  40.  */
  41.  
  42. proc checkDoIO(uint command; *char message)void:
  43.     uint errnum;
  44.  
  45.     MySerReq*.ios_IOSer.io_io.io_Command := command;
  46.     errnum := DoIO(&MySerReq*.ios_IOSer.io_io);
  47.     if errnum ~= 0 then
  48.     writeln(message, " error on serial port: ", errnum);
  49.     fi;
  50. corp;
  51.  
  52. /*
  53.  * setParams - issue an SCMD_SETPARAMS to serial device.
  54.  */
  55.  
  56. proc setParams(bool parity)void:
  57.  
  58.     checkDoIO(CMD_CLEAR, "setParams first clear");
  59.     MySerReq*.ios_CtlChar := 0x11130000;
  60.     MySerReq*.ios_Baud := LineSpeed;
  61.     MySerReq*.ios_TermArray.TermArray0 := 0xff7f1c04;
  62.     MySerReq*.ios_TermArray.TermArray1 := 0x03000000;
  63.     MySerReq*.ios_StopBits := 1;
  64.     if parity then
  65.     MySerReq*.ios_SerFlags := SERF_EOFMODE | SERF_PARTY_ON;
  66.     MySerReq*.ios_ReadLen := 7;
  67.     MySerReq*.ios_WriteLen := 7;
  68.     else
  69.     MySerReq*.ios_SerFlags := SERF_EOFMODE;
  70.     MySerReq*.ios_ReadLen := 8;
  71.     MySerReq*.ios_WriteLen := 8;
  72.     fi;
  73.     checkDoIO(SDCMD_SETPARAMS, "setParms");
  74.     checkDoIO(CMD_CLEAR, "setParams second clear");
  75. corp;
  76.  
  77. /*
  78.  * openSerialHandler - initial open of serial device. Return 'true' if worked.
  79.  */
  80.  
  81. proc openSerialHandler()bool:
  82.  
  83.     MySerPort := CreatePort("MySerial", 0);
  84.     if MySerPort ~= nil then
  85.     MySerReq :=
  86.         pretend(CreateExtIO(MySerPort, sizeof(IOExtSer_t)), *IOExtSer_t);
  87.     if MySerReq ~= nil then
  88.         MySerReq*.ios_IOSer.io_io.io_Flags := SERF_7WIRE;
  89.         if OpenDevice("serial.device", 0,
  90.               &MySerReq*.ios_IOSer.io_io, 0) = 0 then
  91.         SaveParams := MySerReq*;
  92.         LineSpeed := 2400;
  93.         setParams(false);
  94.         LineBuffPos := 0;
  95.         LineBuffMax := 0;
  96.         EchoOn := true;
  97.         SerialDropped := false;
  98.         true
  99.         else
  100.         DeleteExtIO(&MySerReq*.ios_IOSer.io_io, sizeof(IOExtSer_t));
  101.         DeletePort(MySerPort);
  102.         false
  103.         fi
  104.     else
  105.         DeletePort(MySerPort);
  106.         false
  107.     fi
  108.     else
  109.     false
  110.     fi
  111. corp;
  112.  
  113. /*
  114.  * closeSerialHandler - final close of serial device.
  115.  */
  116.  
  117. proc closeSerialHandler()void:
  118.  
  119.     SaveParams.ios_IOSer := MySerReq*.ios_IOSer;
  120.     MySerReq* := SaveParams;
  121.     checkDoIO(SDCMD_SETPARAMS, "close reset params");
  122.     CloseDevice(&MySerReq*.ios_IOSer.io_io);
  123.     DeleteExtIO(&MySerReq*.ios_IOSer.io_io, sizeof(IOExtSer_t));
  124.     DeletePort(MySerPort);
  125.     setDTRoff();
  126. corp;
  127.  
  128. /*
  129.  * readSerial - low-level routine to read a single raw character.
  130.  */
  131.  
  132. proc readSerial()char:
  133.     char ch;
  134.  
  135.     if SerialDropped then
  136.     '\r'
  137.     else
  138.     checkDoIO(SDCMD_QUERY, "Read check");
  139.     /* if connection is dropped, return CR */
  140.     if MySerReq*.ios_Status & CIAF_COMCD ~= 0 then
  141.         SerialDropped := true;
  142.         '\r'
  143.     elif MySerReq*.ios_Status & (IOSTF_READBREAK << 8) ~= 0 then
  144.         '\r'
  145.     elif MySerReq*.ios_Status & (IOSTF_OVERRUN << 8) ~= 0 then
  146.         ' '
  147.     else
  148.         MySerReq*.ios_IOSer.io_Data := pretend(&ch, *byte);
  149.         MySerReq*.ios_IOSer.io_Length := 1;
  150.         checkDoIO(CMD_READ, "Read");
  151.         ch
  152.     fi
  153.     fi
  154. corp;
  155.  
  156. /*
  157.  * writeSerial - low-level routine to write a single raw character.
  158.  */
  159.  
  160. proc writeSerial(char ch)void:
  161.  
  162.     if not SerialDropped then
  163.     MySerReq*.ios_IOSer.io_Data := pretend(&ch, *byte);
  164.     MySerReq*.ios_IOSer.io_Length := 1;
  165.     checkDoIO(CMD_WRITE, "Write");
  166.     fi;
  167. corp;
  168.  
  169. /*
  170.  * serialGetChar - upper level routine to get a character from the serial
  171.  *    port. Echoing is done, as is line editing (backspace, CNTL-X).
  172.  */
  173.  
  174. proc serialGetChar()char:
  175.     char ch;
  176.  
  177.     if LineBuffPos = LineBuffMax then
  178.     LineBuffPos := 0;
  179.     LineBuffMax := 0;
  180.     while
  181.         ch := readSerial();
  182.         if ch = '\r' then
  183.         LineBuffer[LineBuffMax] := '\n';
  184.         LineBuffMax := LineBuffMax + 1;
  185.         writeSerial('\r');
  186.         writeSerial('\n');
  187.         false
  188.         elif ch = '\b' then
  189.         if LineBuffMax ~= 0 then
  190.             LineBuffMax := LineBuffMax - 1;
  191.             if EchoOn then
  192.             writeSerial('\b');
  193.             writeSerial(' ');
  194.             writeSerial('\b');
  195.             fi;
  196.         fi;
  197.         true
  198.         elif ch = '\(0x18)' then
  199.         while LineBuffMax ~= 0 do
  200.             LineBuffMax := LineBuffMax - 1;
  201.             if EchoOn then
  202.             writeSerial('\b');
  203.             writeSerial(' ');
  204.             writeSerial('\b');
  205.             fi;
  206.         od;
  207.         true
  208.         elif ch = '\(0x1c)' then
  209.         LineBuffer[LineBuffMax] := '\e';
  210.         LineBuffMax := LineBuffMax + 1;
  211.         false
  212.         elif ch >= ' ' and ch <= '~' then
  213.         if LineBuffMax < LINE_BUFFER_LENGTH - 1 then
  214.             LineBuffer[LineBuffMax] := ch;
  215.             LineBuffMax := LineBuffMax + 1;
  216.             if EchoOn then
  217.             writeSerial(ch);
  218.             fi;
  219.         fi;
  220.         true
  221.         else
  222.         true
  223.         fi
  224.     do
  225.     od;
  226.     fi;
  227.     LineBuffPos := LineBuffPos + 1;
  228.     LineBuffer[LineBuffPos - 1]
  229. corp;
  230.  
  231. /*
  232.  * serialPutChar - upper level routine to write a character to the serial
  233.  *    port. This one just turns '\n' into CR-LF.
  234.  */
  235.  
  236. proc serialPutChar(char ch)void:
  237.  
  238.     if ch = '\n' then
  239.     writeSerial('\r');
  240.     fi;
  241.     writeSerial(ch);
  242. corp;
  243.  
  244. /*
  245.  * serialEcho - set/clear the echoing flag. (Used for passwords)
  246.  */
  247.  
  248. proc serialEcho(bool enabled)void:
  249.  
  250.     EchoOn := enabled;
  251. corp;
  252.  
  253. /*
  254.  * serialActive - check for a connection. If there is one, set up the baud
  255.  *    rate (2400, 1200, 300) and parity (none or even) and return 'true',
  256.  *    else return 'false'.
  257.  */
  258.  
  259. proc serialActive()bool:
  260.     bool callIncoming;
  261.     char ch;
  262.  
  263.     LineSpeed := 2400;
  264.     setParams(false);
  265.     while
  266.     SerialDropped := false;
  267.     setParams(false);
  268.     checkDoIO(SDCMD_QUERY, "serialActive first query");
  269.     callIncoming := MySerReq*.ios_Status & CIAF_COMCD = 0;
  270.     if callIncoming then
  271.         ch := readSerial();
  272.         Delay(5);
  273.         checkDoIO(SDCMD_QUERY, "serialActive second query");
  274.         callIncoming := MySerReq*.ios_Status & CIAF_COMCD = 0;
  275.     fi;
  276.     callIncoming and ch ~= '\r' and ch ~= '\r' + 0x80
  277.     do
  278.     LineSpeed :=
  279.         if LineSpeed = 2400 then
  280.         1200
  281.         elif LineSpeed = 1200 then
  282.         300
  283.         else
  284.         2400
  285.         fi;
  286.     od;
  287.     if ch = '\r' + 0x80 and callIncoming then
  288.     setParams(true);
  289.     fi;
  290.     SerialDropped := not callIncoming;
  291.     callIncoming
  292. corp;
  293.  
  294. /*
  295.  * serialSpeed - return a string giving the serial connection speed.
  296.  */
  297.  
  298. proc serialSpeed()*char:
  299.  
  300.     if LineSpeed = 2400 then
  301.     "2400"
  302.     elif LineSpeed = 1200 then
  303.     "1200"
  304.     else
  305.     "300"
  306.     fi
  307. corp;
  308.  
  309. /*
  310.  * serialHungup - check to see if the user hung up.
  311.  */
  312.  
  313. proc serialHungup()bool:
  314.  
  315.     if SerialDropped then
  316.     true
  317.     else
  318.     checkDoIO(SDCMD_QUERY, "serialHungup");
  319.     if MySerReq*.ios_Status & CIAF_COMCD ~= 0 then
  320.         SerialDropped := true;
  321.         true
  322.     else
  323.         false
  324.     fi
  325.     fi
  326. corp;
  327.  
  328. /*
  329.  * serialGotControlC - return 'true' if someone typed a control-C.
  330.  */
  331.  
  332. proc serialGotControlC()bool:
  333.     char ch;
  334.     bool gotOne;
  335.  
  336.     if SerialDropped then
  337.     true
  338.     else
  339.     gotOne := false;
  340.     while
  341.         checkDoIO(SDCMD_QUERY, "^C check");
  342.         if MySerReq*.ios_Status & CIAF_COMCD ~= 0 then
  343.         SerialDropped := true;
  344.         gotOne := true;
  345.         elif MySerReq*.ios_Status & (IOSTF_READBREAK << 8) ~= 0 then
  346.         gotOne := true;
  347.         fi;
  348.         not gotOne and MySerReq*.ios_IOSer.io_Actual ~= 0
  349.     do
  350.         MySerReq*.ios_IOSer.io_Data := pretend(&ch, *byte);
  351.         MySerReq*.ios_IOSer.io_Length := 1;
  352.         checkDoIO(CMD_READ, "^C read");
  353.         if ch = '\(0x03)' or ch = '\(0xff)' or ch = '\(0x7f)' then
  354.         gotOne := true;
  355.         fi;
  356.     od;
  357.     if gotOne then
  358.         checkDoIO(CMD_START, "^C start");
  359.         checkDoIO(CMD_CLEAR, "^C clear");
  360.         true
  361.     else
  362.         false
  363.     fi
  364.     fi
  365. corp;
  366.